package com.ruoyi.client.fxiaoke.utils;

import java.util.Map;

import com.google.common.collect.Maps;
import com.ruoyi.client.fxiaoke.beans.args.BaseArg;
import com.ruoyi.client.fxiaoke.beans.results.AppTokenResult;
import com.ruoyi.client.fxiaoke.beans.results.CorpAccessTokenResult;
import com.ruoyi.client.fxiaoke.exception.AccessTokenException;
import com.ruoyi.client.fxiaoke.exception.AppAccessTokenRequestException;
import com.ruoyi.client.fxiaoke.exception.CorpAccessTokenRequestException;
import com.ruoyi.client.utils.TokenModel;

public class TokenUtil {
	private static final String APP_ACCESS_TOKEN_KEY = "appAccessToken";

	private static final String CORP_ACCESS_TOKEN_KEY = "corpAccessToken";


	private static Map<String, TokenModel> accessTokenMap = Maps.newConcurrentMap();

	public static String resetAppAccessToken() throws AppAccessTokenRequestException {
		accessTokenMap.remove(APP_ACCESS_TOKEN_KEY);
		return getAppAccessToken();
	}

	public static TokenModel resetCorpAccessToken() throws AccessTokenException {
		accessTokenMap.remove(CORP_ACCESS_TOKEN_KEY);
		return getCorpAccessToken();
	}

	/**
	 * 获取apptoken
	 * @return
	 * @throws AppAccessTokenRequestException
	 */
	public static String getAppAccessToken() throws AppAccessTokenRequestException {
		TokenModel token = accessTokenMap.get(CORP_ACCESS_TOKEN_KEY);

		if (token != null) {
			if (!token.isExpire()) {
				return token.getToken();
			}
			accessTokenMap.remove(CORP_ACCESS_TOKEN_KEY);
		}

		AppTokenResult result = OpenAPIUtils.getAppToken();

		if (result.getErrorCode() != 0) {
			throw new AppAccessTokenRequestException(result.getErrorCode(), result.getErrorMessage());
		}

		token = new TokenModel(result.getAppAccessToken(), result.getExpiresIn());
		accessTokenMap.put(CORP_ACCESS_TOKEN_KEY, token);
		return token.getToken();
	}

	/**
	 * 获取token
	 * @return
	 * @throws AccessTokenException
	 */
	public static TokenModel getCorpAccessToken() throws AccessTokenException {
		TokenModel token = accessTokenMap.get(APP_ACCESS_TOKEN_KEY);

		if (token != null) {
			if (!token.isExpire() && token.isInit()) {
				return token;
			}
			accessTokenMap.remove(APP_ACCESS_TOKEN_KEY);
		}

		CorpAccessTokenResult corpAccessTokenResult =  OpenAPIUtils.getCorpToken();
		
		if (corpAccessTokenResult != null && corpAccessTokenResult.getErrorCode() == 0) {
			token = new TokenModel(corpAccessTokenResult.getCorpAccessToken(),corpAccessTokenResult.getCorpId(),corpAccessTokenResult.getExpiresIn());
		}

		if (token == null) {
			throw new CorpAccessTokenRequestException(corpAccessTokenResult.getErrorCode(),corpAccessTokenResult.getErrorMessage());
		}
		
		accessTokenMap.put(APP_ACCESS_TOKEN_KEY, token);
		if (token.getToken() == null) {
			throw new CorpAccessTokenRequestException(corpAccessTokenResult.getErrorCode(),corpAccessTokenResult.getErrorMessage());
		}
		
		return token;
	}
	
	public static void setCorpAccessToken(BaseArg arg) throws AccessTokenException {
		TokenModel token = getCorpAccessToken();
		arg.setCorpAccessToken(token.getToken());
		arg.setCorpId(token.getCorpId());
	}
}
